package com.ys.http.network;

import com.ys.http.convert.FastJsonConverterFactory;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

public class HttpHelper {

    private static boolean mShowHttpLog;
    private static HttpLoggingInterceptor.Level mLevel = HttpLoggingInterceptor.Level.BODY;
    private Retrofit mRetrofit;
    private String mBaseUrl = "http://www.test.cn/";

    private static final long READ_TIMEOUT = 30L;
    private static final long WRITE_TIMEOUT = 30L;
    private static final long CONNECT_TIMEOUT = 30L;

    private HttpHelper(){
        System.out.println("-----------http log-->" + mShowHttpLog);
        init(mBaseUrl);
    }

    private static class Holder {
        private static final HttpHelper HELPER = new HttpHelper();
    }

    public static HttpHelper getInstance() {
        return Holder.HELPER;
    }

    private void init(String baseUrl){
        if (mRetrofit == null) {
            baseUrl = parseBaseUrl(baseUrl);
            if (baseUrl != null) {
                mBaseUrl = baseUrl;
            }
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(mBaseUrl)
                    .client(getOkHttpClient())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(FastJsonConverterFactory.create())
                    //.addConverterFactory(GsonConverterFactory.create())
                    .addConverterFactory(ScalarsConverterFactory.create())
                    .build();
        }
    }

    public HttpHelper changeBaseUrl(String baseUrl) {
        baseUrl = parseBaseUrl(baseUrl);
        if (baseUrl != null && !baseUrl.equals(mBaseUrl)) {
            mBaseUrl = baseUrl;
            mRetrofit = mRetrofit.newBuilder()
                    .baseUrl(mBaseUrl)
                    .build();
        }
        return this;
    }

    public <T> T createApi(Class<T> clazz) {
        return mRetrofit.create(clazz);
    }

    public <T> T createApi(Class<T> clazz, String url) {
        return mRetrofit.newBuilder()
                .baseUrl(url)
                .build()
                .create(clazz);
    }

    private String parseBaseUrl(String url) {
        if (url != null) {
            if (url.startsWith("http://") || url.startsWith("https://")) {
                int last = url.length() - 1;
                return url.charAt(last) == '/' ? url : url + '/';
            }
        }
        return null;
    }

    private OkHttpClient getOkHttpClient(){
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (mShowHttpLog) {
            HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();//http log
            logInterceptor.setLevel(mLevel);
            builder.addInterceptor(logInterceptor);
        }
        return builder
                .retryOnConnectionFailure(true)
                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .build();
    }

    public static void setHttpLogDebug(boolean debug) {
        mShowHttpLog = debug;
    }

    public static void setHttpLogLevel(Level level) {
        if (level == Level.NONE) {
            mLevel = HttpLoggingInterceptor.Level.NONE;
        }
        if (level == Level.BASIC) {
            mLevel = HttpLoggingInterceptor.Level.BASIC;
        }
        if (level == Level.HEADER) {
            mLevel = HttpLoggingInterceptor.Level.HEADERS;
        }
        if (level == Level.BODY) {
            mLevel = HttpLoggingInterceptor.Level.BODY;
        }
    }

    public static enum Level {
        NONE,
        BASIC,
        HEADER,
        BODY
    }

}
